﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Serialization;
using System.Xml;
using System.IO;
using System.Xml.Serialization;
using Windows.Storage.Streams;
using Windows.Storage;


namespace Genespy
{
    public class GenespySavedData 
    {

        //Pro Shout out http://irisclasson.com/2012/07/11/example-metro-app-winrt-serializing-and-deseralizing-objects-using-xmlserializer-to-storagefile-and-localfolder-using-generics-and-asyncawait-threading/
        private static List<Report> _data = new List<Report>();

        public static List<Report> Data
        {
            get { return _data; }
            set { _data = value; }
        }

        public static StorageFile file { get; set; }

        private const string filename = "Data.xml";

        static async public Task Save<T>()
        {
            if (await DoesFileExistAsync(filename))
            {
                await Windows.System.Threading.ThreadPool.RunAsync((sender) =>
                    GenespySavedData.SaveAsync<T>().Wait(), Windows.System.Threading.WorkItemPriority.Normal);    
            }
            else
            {
                file = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
            }
        }

        static async public Task Restore<T>()
        {
            if (await DoesFileExistAsync(filename)) // && Check if empty
            {
                try
                {
                    await Windows.System.Threading.ThreadPool.RunAsync((sender) =>
                        GenespySavedData.RestoreAsync<T>().Wait(), Windows.System.Threading.WorkItemPriority.Normal);
                } 
                catch (Exception)
                {
                    // Empty 
                }
                    
            }
            else
            {
                file = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename);
            }
        }

        static async Task<bool> DoesFileExistAsync(string fileName)
        {
            try
            {
                await ApplicationData.Current.LocalFolder.GetFileAsync(fileName);
                return true;
            }
            catch
            {
                return false;
            }
        }

        static async private Task SaveAsync<T>()
        {
            StorageFile sessionFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
            IRandomAccessStream sessionRandomAccess = await sessionFile.OpenAsync(FileAccessMode.ReadWrite);
            IOutputStream sessionOutputStream = sessionRandomAccess.GetOutputStreamAt(0);
            var serializer = new XmlSerializer(typeof(List<Report>), new Type[] { typeof(T) });

            serializer.Serialize(sessionOutputStream.AsStreamForWrite(), _data);
            sessionRandomAccess.Dispose();
            await sessionOutputStream.FlushAsync();
            sessionOutputStream.Dispose();
        }

        static async private Task RestoreAsync<T>()
        {
            StorageFile sessionFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, CreationCollisionOption.OpenIfExists);
            if (sessionFile == null)
            {
                return;
            }
            IInputStream sessionInputStream = await sessionFile.OpenReadAsync();

            var serializer = new XmlSerializer(typeof(List<Report>), new Type[] { typeof(T) });
            _data = (List<Report>)serializer.Deserialize(sessionInputStream.AsStreamForRead());
            sessionInputStream.Dispose();
        }
    }
}
